Skip to main content

Overview

single_stock_analyzer.py is a comprehensive stock analysis utility that extracts and calculates detailed fundamental metrics for any stock from the fundamental_data.json file. It provides deep quarterly and annual financial analysis including P&L statements, ratios, growth metrics, and shareholding patterns.

Purpose

This utility serves to:
  • Deep-Dive Analysis: Examine individual stock fundamentals in detail
  • Quick Lookups: Get instant fundamental snapshot for any symbol
  • Trend Analysis: Calculate QoQ and YoY growth metrics
  • Valuation Metrics: Compute PEG, Forward P/E, and other valuation ratios
  • Shareholding Insights: Track institutional ownership changes

How It’s Used

This is a command-line utility that analyzes data from the main pipeline output:
# Analyze a specific stock
python3 single_stock_analyzer.py RELIANCE

# Analyze another stock
python3 single_stock_analyzer.py TCS
Prerequisite:
  • fundamental_data.json must exist in the same directory (generated by fetch_fundamental_data.py)

What It Analyzes

The analyzer extracts and calculates comprehensive metrics across multiple categories:

1. Profit & Loss (Net Profit)

  • Latest quarter net profit
  • Previous 3 quarters
  • Year-ago quarter (for YoY comparison)
  • QoQ % change
  • YoY % change

2. Earnings Per Share (EPS)

  • Latest quarter EPS
  • Previous 3 quarters
  • Year-ago quarter EPS
  • Last year annual EPS
  • 2 years back annual EPS
  • QoQ % change
  • YoY % change

3. Sales (Revenue)

  • Latest quarter sales
  • Previous 3 quarters
  • Year-ago quarter sales
  • Current year annual sales
  • 5 years ago sales
  • QoQ % change
  • YoY % change
  • 5-Year CAGR (Compound Annual Growth Rate)

4. Operating Profit Margin (OPM)

  • Latest quarter OPM
  • Previous 3 quarters
  • Year-ago quarter OPM
  • TTM (Trailing Twelve Months) OPM
  • QoQ % change
  • YoY % change

5. Valuation Ratios

  • ROE (Return on Equity)
  • ROCE (Return on Capital Employed)
  • P/E Ratio (Price to Earnings)
  • D/E Ratio (Debt to Equity)
  • PEG Ratio (P/E to Growth)
  • Forward P/E (estimated)

6. Shareholding Patterns

  • FII % (Foreign Institutional Investors)
  • DII % (Domestic Institutional Investors)
  • QoQ Change in FII/DII holdings

API Reference

Helper Functions

get_float()

Safely converts a value to float, returning 0.0 on failure.
value_str
any
The value to convert to float (can be string, int, float, or None).
Returns: float
eps = get_float("12.50")  # Returns 12.50
eps = get_float(None)     # Returns 0.0
eps = get_float("N/A")    # Returns 0.0

calculate_change()

Calculates percentage change between two values.
current
float
Current period value
previous
float
Previous period value
Returns: float - Percentage change Formula:
change = ((current - previous) / abs(previous)) * 100
Example:
qoq_growth = calculate_change(100, 80)   # Returns 25.0 (25% growth)
yoy_decline = calculate_change(80, 100)  # Returns -20.0 (20% decline)

get_value_from_pipe_string()

Extracts a specific value from pipe-delimited string.
pipe_string
str
Pipe-delimited string (e.g., “10.5|9.2|8.7|7.5”)
index
int
Zero-based index of the value to extract
Returns: float Example:
# Quarterly data: "12.5|11.0|10.5|9.8"
latest = get_value_from_pipe_string("12.5|11.0|10.5|9.8", 0)  # Returns 12.5
prev = get_value_from_pipe_string("12.5|11.0|10.5|9.8", 1)    # Returns 11.0

Main Function

analyze_stock()

Performs comprehensive fundamental analysis for a given stock symbol.
symbol_to_find
str
Stock symbol to analyze (e.g., “RELIANCE”, “TCS”, “INFY”)
Returns: None (prints analysis to console) Data Sources: The function extracts data from multiple sections of fundamental_data.json:
stock_data = {
    "Symbol": "RELIANCE",
    "incomeStat_cq": {},    # Current Quarter income statement
    "incomeStat_cy": {},    # Current Year annual income statement
    "TTM_cy": {},           # Trailing Twelve Months
    "CV": {},               # Current Valuation
    "roce_roe": {},         # Return ratios
    "sHp": {},              # Shareholding Pattern
    "bs_c": {}              # Balance Sheet Consolidated
}

Output Format

The analyzer prints a detailed report to the console:
--- Analysis for RELIANCE ---

Net Profit Latest Quarter: 15000.0
Net Profit Previous Quarter: 14500.0
Net Profit 2 Quarters Back: 14000.0
Net Profit 3 Quarters Back: 13500.0
Net Profit Last Year Quarter: 12000.0
QoQ % Net Profit Latest: 3.45%
YoY % Net Profit Latest: 25.00%

EPS Latest Quarter: 22.50
EPS Previous Quarter: 21.75
EPS 2 Quarters Back: 21.00
EPS 3 Quarters Back: 20.25
EPS Last Year Quarter: 18.00
QoQ % EPS Latest: 3.45%
YoY % EPS Latest: 25.00%
EPS Last Year: 85.00
EPS 2 Years Back: 75.00

Sales Latest Quarter: 200000.0
Sales Previous Quarter: 195000.0
Sales 2 Quarters Back: 190000.0
Sales 3 Quarters Back: 185000.0
Sales Last Year Quarter: 175000.0
QoQ % Sales Latest: 2.56%
YoY % Sales Latest: 14.29%
Sales Growth 5 Years(%): 12.50%

OPM Latest Quarter: 15.5
OPM Previous Quarter: 15.2
OPM 2 Quarters Back: 14.8
OPM 3 Quarters Back: 14.5
OPM Last Year Quarter: 14.0
QoQ % OPM Latest: 1.97%
YoY % OPM Latest: 10.71%

Latest Quarter: Mar 2024
ROE(%): 12.5
ROCE(%): 14.2
D/E: 0.65
OPM TTM(%): 15.1
P/E: 28.5
FII % change QoQ: 1.25%
DII % change QoQ: -0.50%
PEG: 1.14
Forward P/E: 26.80
Historical P/E 5: 0 (Data Unavailable)

Usage

Command Line

# Analyze a stock
python3 single_stock_analyzer.py RELIANCE

# Without arguments, shows usage
python3 single_stock_analyzer.py
# Output: Usage: python3 analyze_stock.py <SYMBOL>
#         Example: python3 analyze_stock.py RELIANCE

Programmatic Usage

from single_stock_analyzer import analyze_stock

# Analyze a stock programmatically
analyze_stock("TCS")
analyze_stock("INFY")

Source Code

import json
import sys

def get_float(value_str):
    try:
        return float(value_str)
    except (ValueError, TypeError):
        return 0.0

def calculate_change(current, previous):
    if previous == 0:
        return 0.0
    return ((current - previous) / abs(previous)) * 100

def get_value_from_pipe_string(pipe_string, index):
    if not pipe_string:
        return 0.0
    parts = pipe_string.split('|')
    if index < len(parts):
        return get_float(parts[index])
    return 0.0

def analyze_stock(symbol_to_find):
    input_file = "fundamental_data.json"
    
    try:
        with open(input_file, "r") as f:
            data = json.load(f)
    except FileNotFoundError:
        print(f"Error: {input_file} not found.")
        return

    stock_data = None
    for item in data:
        if item.get("Symbol") == symbol_to_find:
            stock_data = item
            break
    
    if not stock_data:
        print(f"Stock '{symbol_to_find}' not found in database.")
        return

    # --- Extract Data Sections ---
    cq = stock_data.get("incomeStat_cq", {})
    cy = stock_data.get("incomeStat_cy", {})
    ttm_cy = stock_data.get("TTM_cy", {})
    cv = stock_data.get("CV", {})
    roce_roe = stock_data.get("roce_roe", {})
    shp = stock_data.get("sHp", {})
    bs_c = stock_data.get("bs_c", {})  # Balance Sheet Consolidated

    # Calculate all metrics (Net Profit, EPS, Sales, OPM, Ratios, etc.)
    # ... [Full calculation logic from source code] ...
    
    # Print comprehensive analysis
    print(f"--- Analysis for {symbol_to_find} ---")
    # ... [Full output format] ...

if __name__ == "__main__":
    if len(sys.argv) > 1:
        analyze_stock(sys.argv[1])
    else:
        print("Usage: python3 analyze_stock.py <SYMBOL>")
        print("Example: python3 analyze_stock.py RELIANCE")
The full source code is 202 lines. See the complete implementation in /workspace/source/DO NOT DELETE EDL PIPELINE/single_stock_analyzer.py

Key Calculations

5-Year Sales CAGR

if sales_5_years_ago > 0:
    sales_growth_5y = ((sales_current_annual / sales_5_years_ago) ** (1/5) - 1) * 100
CAGR Formula: ((End Value / Start Value)^(1/n) - 1) * 100

Debt to Equity Ratio

non_current_liab = get_value_from_pipe_string(bs_c.get("NON_CURRENT_LIABILITIES"), 0)
total_equity = get_value_from_pipe_string(bs_c.get("TOTAL_EQUITY"), 0)
de_ratio = non_current_liab / total_equity if total_equity != 0 else 0.0

PEG Ratio

peg = 0.0
if yoy_eps > 0:
    peg = pe / yoy_eps
PEG = P/E Ratio / EPS Growth Rate

Forward P/E

if eps_latest > 0:
    annualized_eps = eps_latest * 4
    ttm_eps = get_float(ttm_cy.get("EPS"))
    if annualized_eps > 0:
        forward_pe = pe * (ttm_eps / annualized_eps)

Dependencies

  • json: Read fundamental data file
  • sys: Command-line argument handling
This utility has no external dependencies beyond Python standard library.

Error Handling

If fundamental_data.json doesn’t exist:
Error: fundamental_data.json not found.
Solution: Run fetch_fundamental_data.py first to generate the data file.
If the symbol doesn’t exist in the database:
Stock 'INVALID' not found in database.
Solution: Check the symbol spelling or verify it exists in fundamental_data.json.
If a stock has incomplete data, the analyzer returns 0.0 or “N/A” for missing fields rather than crashing.

Use Cases

Quick Screening

Quickly check fundamentals before making investment decisions.

Quarterly Tracking

Monitor quarter-over-quarter performance for portfolio stocks.

Comparative Analysis

Analyze multiple stocks in the same sector by running the script repeatedly.

Automated Alerts

Integrate into scripts to alert when specific metrics cross thresholds.

Integration with Pipeline

While this is a utility script, it integrates seamlessly with the main pipeline:
# Run the pipeline
python3 fetch_fundamental_data.py

# Immediately analyze any stock
python3 single_stock_analyzer.py RELIANCE
You can also create wrapper scripts for batch analysis:
# analyze_watchlist.py
from single_stock_analyzer import analyze_stock

watchlist = ["RELIANCE", "TCS", "INFY", "HDFCBANK", "ICICIBANK"]

for symbol in watchlist:
    analyze_stock(symbol)
    print("\n" + "="*50 + "\n")